﻿using System;
using System.Text.Json.Serialization;

namespace Sgr.Workspace.Models
{
    /// <summary>
    /// 企业用户服务信息
    /// </summary>
    public class EnterpriseUserInfo
    {
        /// <summary>
        /// 当前服务的企业数量
        /// </summary>
        [JsonInclude]
        public int CurrentOrgCount { get; private set; }

        /// <summary>
        /// 上一个周期的企业数量
        /// </summary>
        [JsonInclude]
        public int PrevOrgCount { get; private set; }

        /// <summary>
        /// 当前服务的用户数量
        /// </summary>
        [JsonInclude]
        public int CurrentUserCount { get; private set; }

        /// <summary>
        /// 上一个周期的用户数量
        /// </summary>
        [JsonInclude]
        public int PreUserCount { get; private set; }

        /// <summary>
        /// 近一周企业操作排名
        /// </summary>
        public RankingInfo[]? OpOrgs { get; set; }

        /// <summary>
        /// 近一周用户操作排名
        /// </summary>
        public RankingInfo[]? OpUsers { get; set; }

        /// <summary>
        /// 更新时间
        /// </summary>
        [JsonInclude]
        public DateTime UpdateTime { get; private set; } = DateTime.UtcNow;

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public EnterpriseUserInfo()
        {
        }

        /// <summary>
        /// 带初始值的构造函数
        /// </summary>
        /// <param name="currentEnterpriseCount">当前企业数量</param>
        /// <param name="previousEnterpriseCount">上一周期企业数量</param>
        /// <param name="currentUserCount">当前用户数量</param>
        /// <param name="previousUserCount">上一周期用户数量</param>
        public EnterpriseUserInfo(
            int currentEnterpriseCount,
            int previousEnterpriseCount,
            int currentUserCount,
            int previousUserCount)
        {
            SetValues(currentEnterpriseCount, previousEnterpriseCount, currentUserCount, previousUserCount);
        }

        /// <summary>
        /// 计算变化率
        /// </summary>
        /// <param name="current">当前值</param>
        /// <param name="previous">上一周期值</param>
        /// <returns>变化率百分比</returns>
        public static double CalculateChangeRate(int current, int previous)
        {
            if (previous == 0)
                return current > 0 ? 100.0 : 0.0;

            return ((double)(current - previous) / previous) * 100.0;
        }

        /// <summary>
        /// 更新到新周期的数据
        /// </summary>
        /// <param name="newEnterpriseCount">新周期的企业数量</param>
        /// <param name="newUserCount">新周期的用户数量</param>
        /// <remarks>
        /// 此方法将当前值移动到Previous，并设置新的Current值
        /// 适用于周期性更新场景
        /// </remarks>
        public void UpdateToNewPeriod(int newEnterpriseCount, int newUserCount)
        {
            if (newEnterpriseCount < 0)
                throw new ArgumentException("企业数量不能为负数", nameof(newEnterpriseCount));

            if (newUserCount < 0)
                throw new ArgumentException("用户数量不能为负数", nameof(newUserCount));

            PrevOrgCount = CurrentOrgCount;
            PreUserCount = CurrentUserCount;

            CurrentOrgCount = newEnterpriseCount;
            CurrentUserCount = newUserCount;

            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 设置当前周期和上一周期的值
        /// </summary>
        /// <param name="currentEnterpriseCount">当前企业数量</param>
        /// <param name="previousEnterpriseCount">上一周期企业数量</param>
        /// <param name="currentUserCount">当前用户数量</param>
        /// <param name="previousUserCount">上一周期用户数量</param>
        /// <remarks>
        /// 直接设置所有值，适用于从缓存或数据库恢复数据的场景
        /// </remarks>
        public void SetValues(
            int currentEnterpriseCount,
            int previousEnterpriseCount,
            int currentUserCount,
            int previousUserCount)
        {
            if (currentEnterpriseCount < 0)
                throw new ArgumentException("当前企业数量不能为负数", nameof(currentEnterpriseCount));

            if (previousEnterpriseCount < 0)
                throw new ArgumentException("上一周期企业数量不能为负数", nameof(previousEnterpriseCount));

            if (currentUserCount < 0)
                throw new ArgumentException("当前用户数量不能为负数", nameof(currentUserCount));

            if (previousUserCount < 0)
                throw new ArgumentException("上一周期用户数量不能为负数", nameof(previousUserCount));

            CurrentOrgCount = currentEnterpriseCount;
            PrevOrgCount = previousEnterpriseCount;
            CurrentUserCount = currentUserCount;
            PreUserCount = previousUserCount;

            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 获取企业数量增长数
        /// </summary>
        /// <returns>企业数量增长数</returns>
        public int GetEnterpriseGrowth()
        {
            return CurrentOrgCount - PrevOrgCount;
        }

        /// <summary>
        /// 获取用户数量增长数
        /// </summary>
        /// <returns>用户数量增长数</returns>
        public int GetUserGrowth()
        {
            return CurrentUserCount - PreUserCount;
        }

        /// <summary>
        /// 获取企业数量变化率（百分比，正数表示增长，负数表示下降）
        /// </summary>
        /// <returns>企业数量变化率</returns>
        public double GetOrgChangeRate()
        {
            return CalculateChangeRate(CurrentOrgCount, PrevOrgCount);
        }

        /// <summary>
        /// 获取用户数量变化率（百分比，正数表示增长，负数表示下降）
        /// </summary>
        /// <returns>用户数量变化率</returns>
        public double GetUserChangeRate()
        {
            return CalculateChangeRate(CurrentUserCount, PreUserCount);
        }

        /// <summary>
        /// 检查数据是否有效
        /// </summary>
        /// <returns>数据是否有效</returns>
        public bool IsValid()
        {
            return CurrentOrgCount >= 0 && PrevOrgCount >= 0 &&
                   CurrentUserCount >= 0 && PreUserCount >= 0;
        }

        /// <summary>
        /// 重置所有数据
        /// </summary>
        public void Reset()
        {
            CurrentOrgCount = 0;
            PrevOrgCount = 0;
            CurrentUserCount = 0;
            PreUserCount = 0;
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 返回对象的字符串表示
        /// </summary>
        /// <returns>字符串表示</returns>
        public override string ToString()
        {
            return $"企业: {CurrentOrgCount} , " +
                   $"用户: {CurrentUserCount} , " +
                   $"更新时间: {UpdateTime:yyyy-MM-dd HH:mm:ss}";
        }
    }
}